home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 1833 / 1833.xpi / chrome / yoono.jar / ff2 / bookmarks.js < prev   
Text File  |  2009-12-16  |  14KB  |  446 lines

  1.  
  2. var CI = Components.interfaces;
  3. var CL = Components.classes;
  4.  
  5. const RDF = CL["@mozilla.org/rdf/rdf-service;1"].getService(CI.nsIRDFService);
  6. const ROOTNODE = RDF.GetResource('NC:BookmarksRoot');
  7. var gDataSource = RDF.GetDataSource("rdf:bookmarks").QueryInterface(CI.nsIBookmarksService);
  8. const RDFC = CL["@mozilla.org/rdf/container;1"];
  9.  
  10. const LASTMODIFIED_RESOURCE      = RDF.GetResource("http://home.netscape.com/Web-esd#LastModifiedDate");
  11.  
  12. function start(launch) {
  13.     var _this=this;
  14.     var timer = CL['@mozilla.org/timer;1'].createInstance(CI.nsITimer);
  15.     var callback = {
  16.         notify : function() {
  17.             try {
  18.                 
  19.                 if (!gDataSource.GetTarget(RDF.GetResource('NC:BookmarksRoot'), NAME_RESOURCE, true)) {
  20.                     log.error("Delay bookmarks loading because of RDF :X");
  21.                     return timer.initWithCallback(callback, 1000 , timer.TYPE_ONE_SHOT);
  22.                 }
  23.                 
  24.                 gCurrentTree = new bkmNode('NC:BookmarksRoot', null, true);
  25.                 gToolbarNode = gBkmById[rdfUtils.getValue(gDataSource.getBookmarksToolbarFolder())];
  26.                 
  27.                 
  28.                 // TODO : do not set bkm change observer if non-yet created user
  29.                 //log.error("BKM CHANGE OBSERVER DISABLED DURING WIZARD TESTS");
  30.                 gDataSource.AddObserver(BkmsObserverFF2.rdfObserver);
  31.                 
  32.                 launch();
  33.             } catch(e) {
  34.                 log.exception(e);
  35.             }
  36.         }
  37.     };
  38.     callback.notify();
  39. }
  40.  
  41.  
  42.  
  43.  
  44. var gBrowserBkm = {
  45.  
  46.     runInBatchMode : function (process) {
  47.         
  48.         gDataSource.beginUpdateBatch();
  49.         try {
  50.             process();
  51.         } catch(e) {
  52.             log.exception(e);
  53.         }
  54.         gDataSource.endUpdateBatch();
  55.         
  56.     },
  57.     
  58.     createBookmark : function ( title, url, parent) {
  59.         log.debug(" create bookmark = title:"+title+" url:"+url+" parentId:"+parent.getId());
  60.         var res = gDataSource.createBookmarkInContainer (title, url, '', '', '', null, parent.resource, null);
  61.         return BkmsObserver.onItemAdded(rdfUtils.getValue(res),parent.getId(),-1);
  62.     },
  63.     
  64.     createLivemark : function ( title, url, parent) {
  65.         log.debug(" create livemark = title:"+title+" url:"+url+" parentId:"+parent.getId());
  66.         var res = gDataSource.createLivemarkInContainer (title, '', url, '', parent.resource, null);
  67.         return BkmsObserver.onItemAdded(rdfUtils.getValue(res),parent.getId(),-1);
  68.     },
  69.     
  70.     create : function (node, parent) {
  71.         log.debug(" create from node = nodeId:"+node+" parentId:"+parent.getId());
  72.         if (node.isLive())
  73.             return this.createLivemark(node.getName(),node.getUrl(),node.getParent());
  74.         return this.createBookmark(node.getName(),node.getUrl(),node.getParent());
  75.     },
  76.     
  77.     createFolder : function (name, parent) {
  78.         log.debug(" create folder = title:"+name+" parentId:"+parent.getId());
  79.         
  80.         var res = gDataSource.createFolderInContainer(name, parent.resource, 0);
  81.         return BkmsObserver.onItemAdded(rdfUtils.getValue(res),parent.getId(),-1);
  82.     },
  83.     
  84.     rename : function (node) {
  85.         var oldName = gDataSource.GetTarget(node.resource, NAME_RESOURCE, true);
  86.         log.debug(" rename nodeId:"+node.getId()+" title:"+node.getName()+" res:"+node.resource+" oldName:"+oldName);
  87.         if (oldName)
  88.             gDataSource.Change(node.resource, NAME_RESOURCE, oldName, RDF.GetLiteral(node.getName()));
  89.         else
  90.             gDataSource.Assert(node.resource, NAME_RESOURCE, RDF.GetLiteral(node.getName()),true);
  91.         return BkmsObserver.onItemChanged(node.getId(),"uri",null,null);
  92.     },
  93.     
  94.     remove : function (node) {
  95.         log.debug(" remove bookmark nodeId:"+node.getId());
  96.         var parent = node.getParent();
  97.         var res = node.resource;
  98.         
  99.         var container = RDFC.createInstance(CI.nsIRDFContainer);
  100.         container.Init(gDataSource, parent.resource);
  101.         
  102.         container.RemoveElement(res, false);
  103.         
  104.         // unassert
  105.         var props=gDataSource.ArcLabelsOut(res);
  106.         while(props.hasMoreElements()) {
  107.             var prop=props.getNext();
  108.             var target=gDataSource.GetTarget(res,prop,true);
  109.             gDataSource.Unassert(res,prop,target);
  110.         }
  111.         
  112.         return BkmsObserver.onItemRemoved(rdfUtils.getValue(res),parent.getId(),-1);
  113.     }
  114. }
  115.  
  116.  
  117. ////////////////////////////
  118. // BkmsObserver
  119. // :: observe RDF modifications
  120. // :: init sync system
  121.  
  122. const OBSERVER_DELAY = 2000;  // en ms. Aggregation des evenements d'une manip utilisateur
  123. var BkmsObserverFF2 = {
  124.     _timerInProgress : false,
  125.     _nodeTreeCreated : false,
  126.     rdfObserver : {
  127.         timer : CL['@mozilla.org/timer;1'].createInstance(CI.nsITimer),
  128.         
  129.         launchTimer : function () {
  130.             if (!BkmsObserverFF2._timerInProgress && !Server2Browser.isWorking()) {
  131.                 BkmsObserverFF2._timerInProgress = true;
  132.                 this.timer.initWithCallback(BkmsObserverFF2, OBSERVER_DELAY, this.timer.TYPE_ONE_SHOT);
  133.             }
  134.         },
  135.  
  136.         onBeginUpdateBatch : function(ds) {
  137.             log.debug("BkmsObserver onBeginUpdateBatch");
  138.         },
  139.  
  140.         onEndUpdateBatch : function(ds) {
  141.             log.debug("BkmsObserver onEndUpdateBatch");
  142.             this.launchTimer();
  143.         },
  144.  
  145.         onAssert : function(ds, source, predicate, target) {
  146.             //log.debug("BkmsObserver onAssert");
  147.             //if (predicate == LASTMODIFIED_RESOURCE)
  148.                 this.launchTimer();
  149.         },
  150.  
  151.         onUnassert : function(ds, source, predicate, target) {
  152.             //log.debug("BkmsObserver onUnassert");
  153.             //if (predicate == LASTMODIFIED_RESOURCE)
  154.                 this.launchTimer();
  155.         },
  156.  
  157.         onChange : function(ds, source, predicate, oldTarget, newTarget) {
  158.             //log.debug("BkmsObserver onChange");
  159.             //if (predicate == LASTMODIFIED_RESOURCE)
  160.                 this.launchTimer();
  161.         },
  162.  
  163.         onMove : function(ds, oldSource, newSource, predicate, target) {
  164.             log.debug("BkmsObserver onMove");
  165.         },
  166.     },
  167.  
  168.     notify : function(subject, topic, data) {
  169.         try {
  170.             changesMgr.updateTree();
  171.             this._timerInProgress = false;
  172.         } catch(e) {
  173.             log.exception(e);
  174.         }
  175.     },
  176.     
  177.     forceUpdate : function () {
  178.         
  179.         try {this.timer.cancel();} catch(e) {}
  180.         changesMgr.updateTree();
  181.         
  182.     }
  183. };
  184. //////////////////////////////
  185.  
  186. ////////////////////////////////////
  187. // changesMgr
  188. // :: Parse bookmarks tree (gCurrentTree) to detect user changes
  189.  
  190.  
  191. var changesMgr = {
  192.     changeDetected: false,  // flag to detect changes while updateTree is running
  193.     running: false,  // flag to avoid requesting a sync while updateTree is running
  194.     
  195.     updateTree : function () {
  196.     try {
  197.         if (!gCurrentTree)
  198.             return log.error("bookmarks not already loaded!!!");
  199.         var beginTst = new Date().getTime();
  200.         log.debug('begin updateTree');
  201.         this.changeDetected = false;
  202.         this.running = true;
  203.         for each (var node in gBkmById) {
  204.             node.seen = false;
  205.         }
  206.         var oldNb=yoono.bkm.bookmarksNumber();
  207.         this.traverseTree(RDF.GetResource('NC:BookmarksRoot'), null);
  208.         for each (var node in gBkmById) {
  209.             if (!node.seen)
  210.                 BkmsObserver.onItemRemoved(node.getId(), node.getParent()?node.getParent().getId():null, -1);
  211.         }
  212.         
  213.         log.debug('tree updated after : ' + (new Date().getTime() - beginTst) + 'ms');
  214.         if (oldNb!=yoono.bkm.bookmarksNumber())
  215.             yoono.bkm.dump();
  216.         this.running = false;
  217.     } catch(e) {
  218.         log.exception(e);
  219.     }
  220.     },
  221.  
  222.     traverseTree : function (resource, parent) {
  223.         var node = gBkmById[resource.Value];
  224.         if (node) {
  225.             var name = rdfUtils.getName(resource);
  226.             if (resource==gDataSource.getBookmarksToolbarFolder())
  227.                 name=TOOLBARNAME;
  228.             var url = rdfUtils.getUrl(resource);
  229.             var _haschanged = ( url != node.getUrl()  ||  name != node.getName() );
  230.             var _hasmoved = parent != node.getParent();
  231.  
  232.             if (node.isFolder()) {
  233.                 var container = RDFC.createInstance(CI.nsIRDFContainer);
  234.                 container.Init(gDataSource, resource);
  235.                 var children = container.GetElements()
  236.                 while (children.hasMoreElements()) {
  237.                     var child=children.getNext();
  238.                     if (rdfUtils.getType(child) != SEPARATOR_TYPE)
  239.                         this.traverseTree(child, node);
  240.                 }
  241.             }
  242.  
  243.             if (_haschanged && node!=gCurrentTree) {// ignore changes of root node
  244.                 log.debug("Changed : RES= "+rdfUtils.getName(node.resource)+" URL= '"+url+"' / '"+node.getUrl()+"' NAME= '"+name+"' / '"+node.getName()+"'");
  245.                 if (url != node.getUrl())
  246.                     BkmsObserver.onItemChanged(node.getId(), "uri", null, url);
  247.                 if (name != node.getName())
  248.                     BkmsObserver.onItemChanged(node.getId(), "title", null, name);
  249.             }
  250.             
  251.             if (_hasmoved) {
  252.                 log.debug("Moved : RES= "+rdfUtils.getName(node.resource)+" PARENT= '"+parent);
  253.         /*
  254.         +"' / '"+node.getParent()+"' NAME= '"+name+"' / '"+node.getName()+"'");
  255.         */
  256.                 BkmsObserver.onItemMoved(node.getId(), node.getParent().getId(), -1, parent.getId(), -1);
  257.             }
  258.  
  259.         } else {
  260.             var parentNode = rdfUtils.getParent(resource);
  261.             node = BkmsObserver.onItemAdded(rdfUtils.getValue(resource), parentNode.getId(), -1);
  262.             // notify creation of all sub nodes and mark them as seen
  263.             if (node.isFolder()) {
  264.                 var container = RDFC.createInstance(CI.nsIRDFContainer);
  265.                 container.Init(gDataSource, resource);
  266.                 var children = container.GetElements()
  267.                 while (children.hasMoreElements()) {
  268.                     var child=children.getNext();
  269.                     if (rdfUtils.getType(child) != SEPARATOR_TYPE)
  270.                         this.traverseTree(child, node);
  271.                 }
  272.             }
  273.         }
  274.         //log.debug("Seen >> "+node.getId());
  275.         node.seen = true;
  276.     }
  277.  
  278. }
  279. //////////////////////////////////////
  280.  
  281.  
  282.  
  283. const NAME_RESOURCE           = RDF.GetResource("http://home.netscape.com/NC-rdf#Name");
  284. const URL_RESOURCE            = RDF.GetResource("http://home.netscape.com/NC-rdf#URL");
  285. const FEED_URL_RESOURCE       = RDF.GetResource("http://home.netscape.com/NC-rdf#FeedURL");
  286. const TYPE_RESOURCE           = RDF.GetResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
  287. const TOOLBAR_FOLDER_RESOURCE = RDF.GetResource("http://home.netscape.com/NC-rdf#BookmarksToolbarFolder");
  288. const ID_RESOURCE             = RDF.GetResource("http://home.netscape.com/NC-rdf#ID");
  289. const LINKSTRING_RESOURCE     = "http://www.w3.org/1999/02/22-rdf-syntax-ns#_";
  290.  
  291. const REGULAR_TYPE   = "http://home.netscape.com/NC-rdf#Bookmark";
  292. const SEPARATOR_TYPE = "http://home.netscape.com/NC-rdf#BookmarkSeparator";
  293. const FOLDER_TYPE    = "http://home.netscape.com/NC-rdf#Folder";
  294. const LIVEBKM_TYPE   = "http://home.netscape.com/NC-rdf#Livemark";
  295.  
  296. var rdfUtils = {
  297.     
  298.     getValue : function (target) {
  299.         // resource
  300.         if( target instanceof CI.nsIRDFResource ) {
  301.             return target.Value;
  302.             // LitΘral
  303.         } else if( target instanceof CI.nsIRDFLiteral ) {
  304.             return target.Value;
  305.             // Date
  306.         } else if( target instanceof CI.nsIRDFDate ) {
  307.             return target.Value;
  308.             // Int
  309.         } else if( target instanceof CI.nsIRDFInt ) {
  310.             return target.Value;
  311.         } else {
  312.             return ":blob";
  313.         }
  314.     },
  315.     
  316.     /*
  317.     @param source : une resource RDF
  318.     @return : un noeud de l'arborescence
  319.     */
  320.     getParent: function (resource) {
  321.         function beginsWith(str,substr) {
  322.             return (str.slice(0, substr.length) == substr);
  323.         }
  324.         if (resource == ROOTNODE)
  325.             return null;
  326.         var predicates = gDataSource.ArcLabelsIn(resource);
  327.         while (predicates.hasMoreElements()) {
  328.             var predicate = predicates.getNext();
  329.             
  330.             if (predicate instanceof CI.nsIRDFResource
  331.                     && beginsWith(predicate.Value,LINKSTRING_RESOURCE)) {
  332.                 return gBkmById[rdfUtils.getValue(gDataSource.GetSource(predicate, resource, true))];
  333.             }
  334.         }
  335.         // pas de parent
  336.         return null;
  337.     },
  338.     
  339.     getName: function(resource) {
  340.         var nameRes = gDataSource.GetTarget(resource, NAME_RESOURCE, true);
  341.         if( nameRes ) {
  342.             return nameRes.QueryInterface(CI.nsIRDFLiteral).Value;
  343.         } else {
  344.             return "";
  345.         }
  346.     },
  347.     
  348.     getType : function (source) {
  349.         return rdfUtils.getValue(gDataSource.GetTarget(source, TYPE_RESOURCE, true));
  350.     },
  351.     
  352.     /*
  353.     la source doit etre de type regular ou livebkm,
  354.     cela doit etre verifie avant d'appeler cette fonction
  355.     */
  356.     getUrl : function (source) {
  357.         var urlRes = gDataSource.GetTarget(source, FEED_URL_RESOURCE, true);
  358.         // on utilse FeedUrl pour les live-bookmarks
  359.         if (urlRes && urlRes instanceof CI.nsIRDFLiteral ) {
  360.             var url = urlRes.Value;
  361.             // See ticket #613 about replacing "
  362.             return url ? url.replace(/"/g, '%22') : MAGIC_URL;
  363.         }
  364.  
  365.         urlRes = gDataSource.GetTarget(source, URL_RESOURCE, true);
  366.         if( urlRes instanceof  CI.nsIRDFLiteral) {
  367.             var url =  urlRes.Value;
  368.             // See ticket #613 about replacing "
  369.             return url ? url.replace(/"/g, '%22') : MAGIC_URL;
  370.         }
  371.     }
  372. };
  373. function bkmNode(id, parent, autoCreate) {
  374.     
  375.     this.id=id;
  376.     this.resource=RDF.GetResource(id);
  377.     this.childsList=[];
  378.     this.private=false;
  379.     gBkmById[id] = this;
  380.     
  381.     this.update(parent);
  382.     
  383.     if (autoCreate && this.isFolder()) {
  384.         
  385.         var container = RDFC.createInstance(CI.nsIRDFContainer);
  386.         container.Init(gDataSource, this.resource);
  387.         var children = container.GetElements()
  388.     nbBkms -- ; // do not count folders
  389.         while (children.hasMoreElements()) {
  390.             var child=children.getNext();
  391.             if (rdfUtils.getType(child) != SEPARATOR_TYPE) {
  392.         nbBkms ++;
  393.                 this.childsList.push(new bkmNode(rdfUtils.getValue(child), this, autoCreate));
  394.             }
  395.         }
  396.         
  397.     }
  398.  
  399. }
  400.  
  401. // called on properties update
  402. bkmNode.prototype.update = function (parent) {
  403.     
  404.     var oldParent=this.parent, oldType=this.type, oldName=this.name, oldUrl=this.url;
  405.     
  406.     this.parent=parent?parent:this.parent;
  407.     this.type=rdfUtils.getType(this.resource);
  408.     if (this.resource==gDataSource.getBookmarksToolbarFolder())
  409.         this.name=TOOLBARNAME;
  410.     else
  411.         this.name=rdfUtils.getName(this.resource);
  412.     this.url=rdfUtils.getUrl(this.resource);
  413.     this.path=false;
  414.     
  415.     if (this.isBookmark() || this.isLive()) {
  416.         if (oldUrl)
  417.             delete gBkmByUrl[oldUrl];
  418.         gBkmByUrl[this.getUrl()] = this;
  419.     }
  420.     
  421.     if (oldParent!=this.parent || (this.isFolder() && oldName!=this.name))
  422.         this.traverseNode({onNode:function(node){node.path=false}});
  423.     
  424.     if (oldParent!=this.parent || oldType!=this.type || oldName!=this.name || oldUrl!=this.url) {
  425.         this.syncid=false;
  426.         this.path = false;
  427.         this.resetSyncid();
  428.     //log.debug("updated!");
  429.         return true;
  430.     }
  431. //log.debug("NOT updated!");
  432.     return false;
  433.     
  434. }
  435.  
  436. bkmNode.prototype.isFolder = function () {
  437.     return (this.type==FOLDER_TYPE);
  438. }
  439. bkmNode.prototype.isBookmark = function () {
  440.     return (this.type==REGULAR_TYPE);
  441. }
  442. bkmNode.prototype.isLive = function () {
  443.     return (this.type==LIVEBKM_TYPE);
  444. }
  445.  
  446.